﻿using System;
using System.Linq;
using System.Windows.Forms;
using SVNClean.Modules;
using SVNClean.Windows;
using Microsoft.Win32;
using System.IO;
using SVNClean.Controls;
using SVNClean.Properties;

namespace SVNClean {
    static class Program {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] arguments) {

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            DevExpress.Skins.SkinManager.EnableFormSkins();
            DevExpress.UserSkins.BonusSkins.Register();
            DevExpress.UserSkins.OfficeSkins.Register();

            SvnDirectoryNames.LoadList();
            AppConfiguration.Current.LoadData();

            #region "[rgn] System Path Registration    "
            using (var registry = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, Environment.MachineName)) {
                var key = registry.CreateSubKey(string.Concat(@"SOFTWARE\KEYROX\SVNCLEANER\"), RegistryKeyPermissionCheck.ReadWriteSubTree);
                key.SetValue("PATH", Path.Combine(Application.StartupPath, "SVNClean.exe"));
            }
            #endregion

            #region "[rgn] Unhandled Exception Handler "
            Win32.AddERExcludedApplication("SVNClean.exe");
            Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
            Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            #endregion

            #region "[rgn] Check Shell Arguments       "
            var argstr = string.Empty;
            for (var i = 0; i < arguments.Length; i++) { argstr += arguments[i]; if (i != (arguments.Length - 1)) { argstr += " "; } }
            //MessageBox.Show(arguments.Length.ToString());
            //MessageBox.Show(argstr); return;

            if (argstr != string.Empty) {

                if (argstr.ToLower().StartsWith("clearbackup")) {
                    var path = argstr.Substring(argstr.IndexOf("clearbackup") + 12, argstr.Length - 12).TrimStart(' ').TrimEnd(' ');
                    //MessageBox.Show(path);
                    var dir = new DirectoryInfo(path);
                    if (dir.Exists) {
                        var result = MessageBox.Show("A backup will be created and after this directory will cleaned!\nContinue?", "SVN Cleaner", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                        if (result == DialogResult.Yes) {
                            AppConfiguration.Current.CreateBackup = true;
                            AppConfiguration.Current.SaveData();
                            Application.Run(new frm_Clean() { DirectoryToClean = dir });
                        }
                        return;
                    }
                    else { MessageBox.Show("Directory not found!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
                }
                else if (argstr.ToLower().StartsWith("clear")) {
                    var path = argstr.Substring(argstr.IndexOf("clear") + 6, argstr.Length - 6).TrimStart(' ').TrimEnd(' ');
                    //MessageBox.Show(path);
                    var dir = new DirectoryInfo(path);
                    if (dir.Exists) {
                        var result = MessageBox.Show("This directory will cleaned!\nContinue?", "SVN Cleaner", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
                        if (result == DialogResult.Yes) {
                            AppConfiguration.Current.CreateBackup = false;
                            AppConfiguration.Current.SaveData();
                            Application.Run(new frm_Clean() { DirectoryToClean = dir });
                        }
                        return;
                    }
                    else { MessageBox.Show("Directory not found!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
                }                
                else if (argstr.ToLower().StartsWith("count")) {
                    var path = argstr.Substring(argstr.IndexOf("count") + 6, argstr.Length - 6).TrimStart(' ').TrimEnd(' ');
                    var dir = new DirectoryInfo(path);
                    //MessageBox.Show(path);
                    if (dir.Exists) {
                        ctrl_Explorer.CountSVNReferences(dir);
                    }
                    else { MessageBox.Show("Directory not found!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }
                }
                else {
                    MessageBox.Show("Invalid arguments!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
            }
            #endregion

            Application.Run(new frm_Main());
        }

        /// <summary>
        /// Handles the UnhandledException event of the CurrentDomain.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.UnhandledExceptionEventArgs"/> instance containing the event data.</param>
        public static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
            AppConfiguration.Current.LastCleanedDirectory = string.Empty;
            AppConfiguration.Current.SaveData();
            Exception ex = (Exception)e.ExceptionObject;
            MessageBox.Show(ex.Message + "\n" + ex.Source + "\n\n" + ex.StackTrace, "Critical Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        /// <summary>
        /// Handles the ThreadException event of the Application.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Threading.ThreadExceptionEventArgs"/> instance containing the event data.</param>
        public static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e) {
            CurrentDomain_UnhandledException(sender, new System.UnhandledExceptionEventArgs(e.Exception, false));
        }

    }
}
